home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / dict / _ch_array.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  3.8 KB  |  220 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _ch_array.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/impl/ch_array.h>
  16.  
  17. //------------------------------------------------------------------------------
  18. //
  19. //  hashing array with chaining and table doubling
  20. //
  21. //  only integer/pointer keys
  22. //  no delete operation
  23. //
  24. //  S. Naeher (1994)
  25. //
  26. //------------------------------------------------------------------------------
  27.  
  28.  
  29. ch_array_elem ch_array::STOP;
  30.  
  31. #define NIL  GenPtr(this)
  32.  
  33. /* #define HASH(x) (table + (int(x) & table_size_1)) */
  34.  
  35. #define HASH(x) (table + ((int(x)>>shift) & table_size_1))
  36.  
  37.  
  38. ch_array::ch_array(GenPtr i, int s, int n) 
  39. { init_val = i; 
  40.   shift = 0;
  41.   while (s/=2) shift++;
  42.   int ts = 1;
  43.   while (n/=2) ts *= 2;
  44.   if (ts < 512) ts = 512;
  45.   init_table(ts); 
  46. }
  47.  
  48.  
  49.  
  50. GenPtr ch_array::lookup(GenPtr x) const
  51. { ch_array_item p = HASH(x);
  52.   STOP.k = x;
  53.   while (p->k != x) p = p->succ;
  54.   return (p == &STOP) ? nil : p;
  55. }
  56.  
  57.  
  58. GenPtr ch_array::access(GenPtr x) const
  59. { ch_array_item p = HASH(x);
  60.   STOP.k = x;
  61.   while (p->k != x) p = p->succ;
  62.  
  63.   return (p == &STOP) ? init_val : p->i;
  64. }
  65.  
  66.  
  67. GenPtr& ch_array::access(GenPtr x)
  68. { ch_array_item p = HASH(x);
  69.  
  70.   if (p->k == x) return p->i;
  71.  
  72.   if (p->k == NIL)
  73.     { p->k = x;
  74.       p->i = init_val;
  75.       copy_inf(p->i);
  76.       return p->i;
  77.      }
  78.  
  79.  
  80.   STOP.k = x;
  81.   ch_array_item q = p->succ; 
  82.   while (q->k != x) q = q->succ;
  83.   if (q != &STOP) return q->i;
  84.  
  85.   if (free == table_end) 
  86.   { rehash();
  87.     p = HASH(x);
  88.    }
  89.  
  90.   free->k = x;
  91.   free->i = init_val;
  92.   copy_inf(free->i);
  93.   free->succ = p->succ;
  94.   p->succ = free++;
  95.  
  96.   return p->succ->i;
  97. }
  98.  
  99.  
  100.  
  101.  
  102. void ch_array::destroy() 
  103. { ch_array_item p;
  104.   for (int i=0; i<table_size; i++)
  105.   { p = table+i;
  106.     if (p->k != NIL) 
  107.       while(p != &STOP)
  108.       { clear_inf(p->i);
  109.         p = p->succ;
  110.        }
  111.    }
  112.   delete[] table; 
  113. }
  114.  
  115.  
  116. void ch_array::init_table(int T)
  117.   table_size = T;
  118.   table_size_1 = T-1;
  119.  
  120.   table = new ch_array_elem[2*T];
  121.  
  122.   free      = table + table_size;
  123.   table_end = free + T;
  124.  
  125.   for(ch_array_item p=table; p<free; p++) 
  126.   { p->k = NIL;
  127.     p->succ = &STOP;
  128.    }
  129. }
  130.  
  131.  
  132. #define INSERT(x,y)\
  133. { ch_array_item q = HASH(x);\
  134.   if (q->k == NIL)\
  135.     { q->k = x;\
  136.       q->i = y;\
  137.      }\
  138.   else\
  139.    { free->k = x;\
  140.      free->i = y;\
  141.      free->succ = q->succ;\
  142.      q->succ = free++;\
  143.    }\
  144. }
  145.  
  146.  
  147. void ch_array::rehash()
  148.   ch_array_item old_table = table;
  149.   ch_array_item old_table_end = table_end;
  150.   ch_array_item stop = table+table_size;
  151.  
  152.   init_table(2*table_size);
  153.  
  154.   ch_array_item p = old_table;
  155.  
  156.   while (p < stop)
  157.   { if (p->k != NIL) INSERT(p->k,p->i);
  158.     p++;
  159.    }
  160.  
  161.   while (p < old_table_end)
  162.   { INSERT(p->k,p->i);
  163.     p++;
  164.    }
  165.  
  166.   delete[] old_table;
  167. }
  168.  
  169.  
  170. ch_array::ch_array(const ch_array& D)
  171. { ch_array_item p;
  172.   init_table(D.table_size);
  173.   init_val = D.init_val;
  174.   for (int i=0; i<table_size; i++)
  175.   { p = D.table[i].succ;
  176.     while(p != &STOP)
  177.     { INSERT(p->k,p->i);
  178.       D.copy_inf(p->i);
  179.       p = p->succ;
  180.     }
  181.   }
  182. }
  183.  
  184.  
  185. ch_array& ch_array::operator=(const ch_array& D)
  186. { destroy();
  187.   init_table(D.table_size);
  188.   init_val = D.init_val;
  189.   for (int i=0; i<D.table_size; i++)
  190.   { ch_array_item p = D.table + i;
  191.     if (p->k != NIL)
  192.      while(p != &STOP)
  193.      { INSERT(p->k,p->i);
  194.        copy_inf(p->i);
  195.        p = p->succ;
  196.       }
  197.    }
  198.   return *this;
  199. }
  200.  
  201.  
  202. void ch_array::print()
  203. { cout << "shift = " << shift << endl;
  204.   for (int i=0; i<table_size; i++)
  205.   { ch_array_item p = table + i;
  206.     if (p->k != NIL)
  207.     { int l = 0;
  208.       while(p != &STOP)
  209.       { l++; 
  210.         p = p->succ;
  211.        }
  212.       cout << string("L(%d) = %d",i,l) << endl;
  213.      }
  214.    }
  215. }
  216.   
  217.